''' 花式索引：计算 shape 和 广播机制 '''
import numpy as np

arr4 = np.arange(480).reshape(4, 6, 5, 4)
# 4维数组，(4, 6, 5, 4)
# axis   = 0  1  2  3
''' 格式： arr4[索引数组1, 索引数组2, ...] '''
# 1. 索引数组的个数不能超过 4，索引数组1 和 索引数组2 shape 一样
print(arr4[[0, 1, 2, 3], [5, 3, 2, 4], [4, 2, 3, 1], [3, 2, 1, 0]])

# 2. 广播：索引数组1 和 索引数组2 在同轴上元素个数相同 或 1个整数【1个】
print(arr4[[0, 1, 2, 3], [5, 3, 2, 4], [4], [3, 2, 1, 0]])
print(arr4[[0, 1, 2, 3], [5, 3, 2, 4], 3, [3, 2, 1, 0]])
# [4] --》 【4，4，4，4】

print(arr4[:, [[5, 3, 2, 4], [5, 3, 2, 4]], :, [3, 2, 1, 0]])
# [[5,3,2,4], [5,3,2,4]]  行，列
# [3,2,1,0]  列  【[3,2,1,0] ，[3,2,1,0]】


# 3. 计算 shape = (4, 6, 5, 4)
'''# 1）索引数组如果是一个，对某一个轴进行操作，只改变该轴的值，其他轴不动'''
print(arr4[:, [[5, 3, 2, 4], [5, 3, 2, 4]], :, :].shape)
# 对 axis = 1 操作，shape=(4, ?, 5, 4) --》(4, 索引数组的shape, 5, 4)
# shape=(4, 2*4, 5, 4)   -->  shape=(4, 2, 4, 5, 4)

'''# 2）索引数组，对多个连续的轴进行操作，不改变轴的值前面加广播后的索引数组的 shape '''
print('#' * 50)
print(arr4[:, [[5, 3, 2, 4], [5, 3, 2, 4]], [1, 2, 3, 0], :].shape)
# 对轴操作，如果轴连续 1,2轴。shape=(4, ?, ？, 4) --》(4, 索引数组的shape, 4)
# shape=(4, ？, ？, 4) --》 （4， 2，4， 4）


'''# 3）索引数组，对多个不连续的轴进行操作，不改变轴的值前面加广播后的索引数组的 shape '''
print(arr4[:, [[5, 3, 2, 4], [5, 3, 2, 4]], :, [1, 2, 3, 0]].shape)
# 对 axis = 1 和 3 轴进行操作操作，0 和 4不变，前面添加索引数组
# shape=(4, ?, 5, ？) --》 shape= (索引数组shape, 4,5) = (2,4,4,5)

print(arr4[:, [5, 3, 2, 4], :, [[[1, 2, 3, 0], [1, 2, 3, 0]], [[1, 2, 3, 0], [1, 2, 3, 0]]]].shape)
# shape=(4, ?, 5, ？) --》 shape= (索引数组shape, 4,5) = (2,2,4,  4,5)

arr3 = np.arange(36).reshape(2, 3, 2, 3)
# print(arr3)
print('#' * 100)
print(arr3[:, [1, 0, 2], [0, 1, 0], :].shape)  # shape= 2, 3, 3
print(arr3[:, [1, 0, 2], [0, 1, 0], :])
print('#' * 100)
print(arr3[:, [1, 0, 2], :, [0, 1, 0]].shape)  # shape= 3, 2, 2
print(arr3[:, [1, 0, 2], :, [0, 1, 0]])

# ---------------- 06-16

arr5 = np.arange(101, 133).reshape(2, 2, 2, 2, 2)
print(arr5[:, [0, 1, 1], [1, 0, 1], :, [0, 1, 0]])

# print(arr5[:,[0,1,1],:,[0,1,1],:])
#
# print(arr5[:,[0,1,1],[0,1,1],:,:])


# 1.连续索引数组：  shape其他轴不变 --》 axis=1变   shape(axis=0,  索引数组shape, axis=2)
# 取值：对应轴取值，取 axis=0， 0取完，再取1

# 2.不连续索引数组：shape其他轴不变，axis=1，3变，   shape(索引数组shape, axis=0, axis=2)
# 取值：对应轴第一个值，取 axis=0， 0，1取值， 对应轴第二个值，取 axis=0， 0，1取值


''' 4. 布尔索引：返回布尔值 True、False 可以使用逻辑符 &-与  |=或 连接多个布尔索引 '''
print('#' * 100)
arr3 = np.arange(1, 25).reshape(2, 3, 4)
print(arr3)
print(arr3 > 0)  # 10 广播 （2，3，4），对应位置比较值，True

print('#' * 100)
print((arr3 > 10) & (arr3 < 15))  # 与
print((arr3 > 15) | (arr3 < 10))  # 或

print(arr3[arr3 > 10])  # 先广播比较10，返回 True，会拉平

# 布尔索引修改值：ndarray[布尔索引] = 值
print('#' * 100)
arr3[arr3 > 10] = 100
print(arr3)

print('#' * 100)
''' 格式：np.where(条件表达式, [条件为真返回值1, 条件为假返回值2]) 
    where 没有赋值，返回 对应 axis 的索引值位置
    where 有赋值，返回具体的值，为真返回值1，否则返回值2
'''
print(arr3)
print(np.where(arr3 > 10))
# (array([0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]),   axis=0 索引 0，1
#  array([2, 2, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]),   axis=1 索引 0，1，2
#  array([2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]))   axis=2 索引 0，1，2，3

# np.int64()
# np.float32()

print(np.where(arr3 > 12, 1, 0))

''' 5. 伪索引 np.newaxis = None：增加维度 '''
# np.newaxis 在切片索引时，增加维度
print('#' * 100)
arr2 = np.arange(12).reshape(3, 4)
print(arr2)

print(arr2[:, np.newaxis, :])  # (3,1,4)
print(arr2[:, :, None])
print(arr2[np.newaxis, :, :])

# shape(4, 1) + shape(1, 4) = ?

arr3d = np.arange(1, 61).reshape(3, 5, 4)

# sub_arr = arr3d[:, 2, :]

print(arr3d[:, 2, :][arr3d[:, 2, :] % 2==0])

# arr3d[:, 2, :] = 1
# print(np.isin(arr3d, arr3d[:, 2, :]))
# a = np.where(np.isin(arr3d, arr3d[:, 2, :]), 1, 0)
# print(a)

# isin(数组, 子数组)  比较 2个数组（shape一样）元素是否相同，返回 True
